<?php
namespace app\api\controller;
use think\Controller;
use think\Session;
use think\Db;

class Activetest extends Controller {
	
    //根据卡号用积分兑换券
	public function exchange($username,$mobile,$CardHyNo,$cardLevel,$couponId,$actionId,$score){
		$apilog = new Common();
		//会员名称
		$username = input('username',$username);
		//手机号
		$mobile = input('mobile',$mobile);
		//会员卡号
		$cardhyno = input('CardHyNo',$CardHyNo);
		//卡级
		$cardLevel = input('cardLevel',$cardLevel);
		//券id 
		$couponId = input('couponId',$couponId);
		//活动id 
		$action_id = input('actionId',$actionId);
		//扣减积分值
		$score = input('score',$score);
		//添加锁标识，加锁
//		$redisLock = new Redislock();
//		$redisLock->lock($mobile.$couponId,3,1);
		//查券剩余库存,
		$coupon = Db::name('coupon')
			->where('id',$couponId)
			->lock(true)
			->find();
		//库存不足,停止
		if($coupon['real_stock']<=0){
			rtnError('此券库存不足',$coupon['real_stock']);
		}
		//有库存，库存先减一（加锁）
		$couponReal = Db::name('coupon')
			->where('id',$couponId)
    		->setDec('real_stock', 1);
    	//面值，扣减积分值
		$certime = $coupon['point'];
		//促销单号
		$cxbillno = $coupon['promotion_num'];
		//券备注
		$cxremark = $coupon['cxremark'];
    	//扣减积分
    	$sendResult = $this->decScore($cardhyno,$score);
    	if($sendResult){
    		//扣减积分成功
    	}else {
    		//扣减积分失败，库存加一
			$couponReal = Db::name('coupon')
				->where('id',$couponId)
	    		->setInc('real_stock', 1);
    		//扣减积分失败，终止
			rtnError('领券失败',$sendResult);
    	}
		//获取最后一条记录的赠券号（加锁，阻止其他人查询）
		$certino = $this->creatCertino($mobile,$couponId);
		//插入领券记录数据
		$exchange = [
	    	'mobile' => $mobile,
	    	'coupon_id' => $couponId,
	    	'gettime' => date('Y-m-d H:i:s'),
	    	'username' => $username,
	    	'point' => $certime,
	    	'cardHyNo' => $cardhyno,
	    	'certino' => $certino,
	    	'cardLevel' => $cardLevel,
	    	'action_id' => $action_id
	    ];
	    try{
	    	//添加一条 未发送 状态的 发券记录
	    	$exchangeId = Db::name('exchange')
				->insertGetId($exchange);
	    }catch (\Exception $e){
	    	//发送失败库存，库存加一
			$couponReal = Db::name('coupon')
				->where('id',$couponId)
	    		->setInc('real_stock', 1);
			rtnError('系统繁忙，请稍后再试',$e);
        }
		//				释放锁 查询记录锁
//		$redisLock->unlock($mobile.$couponId);
//		$certino = $certino.rand(10000,99999);
		//校验码，4位随机数
		$rand = rand(1000, 9999);
		$postData = array(
			'CXBILLNO' => $cxbillno, // ————促销单号（后台配置）
			'CERTINO' => $certino, //  ————赠券号（传入时我方生成，赠券号以89开头 89yymmdd12345后面是2位年月日然后是5位顺序码，举例0018042300001 ）
			'CHECKCODE' => $rand, //校验码  qd.hisense.sylwtech.cn
			'CERTIME' => $score, //  ————面值   lucky_girls_day 
			'CXREMARK' => $cxremark, // ————备注（相当于券说明，后台传入）K5LcxCcBmkKZ8YKw
			'CARDHYNO' => $cardhyno, // ————会员卡 卡面号
			'WEIXININFO' => '', 'USBGNDATE' => '', 'USENDDATE' => ''
		);
		//发券
//		$url = "http://123.235.28.142:8080/ApplyCertiForeign01.asmx";
//		$SOAPAction = "http://tempuri.org/ApplyCertiForeign01Func";
//		$data = '<?xml version="1.0" encoding="utf-8"     ? >
//			<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
//			  <soap:Body>
//			    <ApplyCertiForeign01Func xmlns="http://tempuri.org/">
//			      <sjson>['.json_encode($postData).']</sjson>
//			      <UserId>10020000051158</UserId>
//			      <PassWord>108F12E9AEF9203E</PassWord>
//			    </ApplyCertiForeign01Func>
//			  </soap:Body>
//			</soap:Envelope>';
//		$result = GetYktEmpInfo($url,$SOAPAction,$data);
		$result = true;
		
		//检查错误，获取返回值
		if ($result) {
			$sendTime = date('Y-m-d H:i:s');
//			$jsonstr = $result->ApplyCertiForeign01FuncResponse->ApplyCertiForeign01FuncResult;
//			$domain = strstr($jsonstr, "'1'");
			$jsonstr = "success";
			$domain = true;
			if ($domain == false) {
				//领券失败，日志
//				$apilog->dataFormat($postData,$jsonstr,'/api/Active/exchange',$message = '领券接口领取失败',0);
				rtnError('领券失败',2);
			} else {
				//领券成功，日志
				$apilog->dataFormat($postData,$jsonstr,'/api/Active/exchange',$jsonstr,"json","领取券接口成功");
				//插入记录
			    Db::name('exchange')
					->where('id',$exchangeId)
					->update(['status'=>1]);
//				rtnSuccess('领券成功');
				return json_encode([
					'exchangeId' => $exchangeId,
					'msg' => 'success'
				]);
			}
		} else {
			//接口调用失败，日志
//			$apilog->dataFormat($postData,$result,'/api/Active/exchange',$message = '领券接口错误',0);
			rtnError('领券失败',3);
		}
	}
	
	//扣除积分
    public function decScore($card,$score){
		$apilog = new Common();
    	$postData = [
    		'card' => $card,
    		'score' => $score
    	];
        $sign = json_decode($this->connectMysql());
        $guid = $sign->workGuid;
        $key = $sign->key;
        // 输入报文中的随机整数，目的是为了使报文的长度不固定，从而影响加密结果以混淆报文
        $random = rand ( 10, 99 );
        // 输入报文格式
//      $body = '<?xml version="1.0" encoding="UTF-8"? >
//          <InputParameter>
//              <RandomNo>'.$random.'</RandomNo>
//              <UserCode>qdxx08</UserCode>
//              <WorkGuid>'.$guid.'</WorkGuid>
//              <OrgCode>1008</OrgCode>
//              <POSNo>001</POSNo>
//              <CardNoType>1</CardNoType>
//              <CardNo>'.$card.'</CardNo>
//              <PrjCode>2001</PrjCode>
//              <OldBillNo>'.time().rand(100000,999999).'</OldBillNo>
//              <Remark></Remark>
//              <FlType>0</FlType>
//              <BillType>1</BillType>
//              <BillNo></BillNo>
//              <DepCode>01</DepCode>
//              <TerminalNo></TerminalNo>
//              <ComputerName></ComputerName>
//              <FlKind>0</FlKind>
//              <SFlJfTotal>'.$score.'</SFlJfTotal>
//              <SFlTotal></SFlTotal>
//          </InputParameter>';
//      //echo $body;die;
//      require_once("Java.inc");
//      $des = new \Java('RSAEncrpt.DES3');
//
//      $body = $des->encrypt($body,$key);
//      $tag = strtoupper(md5($body.'ABCD'));
//
//      $para = '<?xml version="1.0" encoding="UTF-8" ? >
//          <InputParameter>
//              <Head><ClientCode>001</ClientCode><Tag>'.$tag.'</Tag></Head>
//              <Body>'.$body.'</Body>
//          </InputParameter>';
//
//      $client = new \SoapClient("http://60.30.83.101:1144/HisComSvr/HsCRMWebSrv.dll/wsdl/IHsCRMWebSrv?wsdl");
//      $output = $client->IWsPosCommOperate ( '107', $para );
		if($random){
//      if ($output->ReturnCode == 0){
//          $rst = $des->decrypt($output->OutputPara,$key);
//          $rst = xmlToArray($rst);
			$rst = true;
//			$apilog->dataFormat($postData,$rst,'/api/Active/decScore',$message = '扣减积分成功',1);
            return json_encode($rst);
        } else {
        	//接口调用失败，日志
//			$apilog->dataFormat($postData,"false",'/api/Active/decScore',$message = '扣减积分接口错误',0);
			return false;
//		    echo iconv("GBK","UTF-8", base64_decode($output->RtnMsg));
        }
    }
    //生成赠券号
    public function creatCertino($mobile,$couponId){
//  	$this->addlock($mobile.$couponId);
    	$findOrder = Db::name('exchange')
    		->lock(true)
			->order("id desc")
			->field("id,certino")
			->select();
//		$this->dellock($mobile.$couponId);
		//生成赠券号
		$dateTime = date("ymd");
		if (empty($findOrder)) {
			$order = "00001";
			$certino = "89" . $dateTime . $order;
		} else {
			$certinoTest = $findOrder[0]['certino'];
			$order = substr($certinoTest, -5) + 1;
			$if = strlen($order);
			if ($if < 5) {
				for ($i = 0; $i = 5 - strlen($order); $i++) {
					$order = "0" . $order;
				}
			}
			$certino = "89" . $dateTime . $order;
		}
		return $certino;
    }
    //跨数据库读数据
    public function connectMysql(){
    	$result = Db::connect('db_saas');
    	$sign = $result->table('sylw_zapi1_actionlist')->where("id","=",1)->find();
		$data = [
			'guid' => $sign['workGuid'],
            'key' => $sign['key']
		];
		return json_encode($sign);
    }
    //添加活动点击记录
    public function actionClick(){
    	$action_id = input("actionId");
    	$mobile = input("mobile");
    	$addData = [
    		'action_id' => $action_id,
    		'mobile' => $mobile,
    		'hittime' => date("Y-m-d H:i:s")
    	];
    	$insertId = Db::name('action_hit')
    		->insertGetId($addData);
    	rtnSuccess('点击成功',$insertId,1);
    }
    
    //测试高并发
    public function testSend(){
		$redis=new \Redis();
        $connectredis = $redis->connect(config('redis.REDIS_HOST'),config("redis.REDIS_PORT"));       
        $couponId = input('couponId');
		$actionId = input('actionId');
       	$CardHyNo='54976'.rand(10,99);
		$username='测试用户'.rand(10,99);
		$mobile='1501234'.rand(1000,9999);
		$cardLevel='准会员';
		$score = rand(1,100);
		$sendNumber = 0;
		for($i = 0;$i<70;$i++){
			$this->addlock($mobile.$couponId);
			$re = $this->exchange($username,$mobile,$CardHyNo,$cardLevel,$couponId,$actionId,$score);
			$this->dellock($mobile.$couponId);
			$sendNumber++;
		}
		return $sendNumber;
    }
    
    /*
     	加锁
     * */
    public function addlock($couponId){
    	$redis=new \Redis();
        $connectredis = $redis->connect(config('redis.REDIS_HOST'),config("redis.REDIS_PORT"));       
       	$lock_key = 'LOCK_PREFIX' . $couponId;
		$is_lock = $redis->setnx($lock_key, 1); // 加锁
		return $is_lock;
    }
    /*
     	释放锁
     * */
    public function dellock($couponId){
    	$redis=new \Redis();
        $connectredis = $redis->connect(config('redis.REDIS_HOST'),config("redis.REDIS_PORT"));       
       	$lock_key = 'LOCK_PREFIX' . $couponId;
		$redis->del($lock_key);
		return;
    }
    
    
    
    /**
        * redis连接
        * @access private
        * @return resource
        * @author bieanju
        */
    public function connectRedis(){
        $redis=new \Redis();
        $connectredis = $redis->connect(config('redis.REDIS_HOST'),config("redis.REDIS_PORT"));       
        return json_encode($connectredis);
    }
}
